{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "318cd7f7",
   "metadata": {},
   "source": [
    "# overview\n",
    "feature engineeing includes <font color=burgendy><b>feature seletion</b></font> and <font color=burgendy><b>feature extraction</b></font>\n",
    "## feature selection\n",
    "1. could be divided into filter, wrapper, embedded and hybrid\n",
    "2. filter is more easy to accomplish\n",
    "\n",
    "\n",
    "    > feature selection more focuses on finding multicollinearity between features or correlations between dependent and independent variables.\n",
    "    > most basic and intuitive method could be droping features that are not relative at the first glance and features with many missing values"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "137ab04e",
   "metadata": {},
   "source": [
    "# MI and IG\n",
    "1. Mutual Information and Information Gain are the same concept, the only difference is that MI will determine whether two random variables would be independent to each other, while IG will calculate the value when one feature is taken into consideration, how much information it would contribute to total change of dependent variable."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3fcdb59",
   "metadata": {},
   "source": [
    "note that MI and IG shares the same formula, which is:\n",
    "$$\n",
    "\\left\\{\n",
    "\\begin{array}{ll}\n",
    "    I(X;Y) & = & H(X) - H(X|Y) = H(Y) - H(Y|X) \\\\\n",
    "    H(X|Y) & = & -\\sum_{y \\in Y} {p(y)H(X|Y=y)} \\\\\n",
    "    & = & -\\sum_{y \\in Y}{p(y)}\\sum_{x \\in X}{p(x|y)log{p(x|y)}} \\\\\n",
    "    & = & -\\sum_{y \\in Y}{\\sum_{x \\in X}{p(x,y)log\\frac{p(x,y)}{p(y)}}} \\\\\n",
    "    I(X;Y) & = & -\\sum_{x \\in X}{p(x)logp(x)} + \\sum_{y \\in Y}{\\sum_{x \\in X}{p(x,y)log\\frac{p(x,y)}{p(y)}}}\\\\\n",
    "    & = & -\\sum_{x \\in X}{\\sum_{y \\in Y}{p(x,y)logp(x)}} + \\sum_{y \\in Y}{\\sum_{x \\in X}{p(x,y)log\\frac{p(x,y)}{p(y)}}} \\\\\n",
    "    & = & \\sum_{y \\in Y}{\\sum_{x \\in X}{p(x,y)log\\frac{p(x,y)}{p(x)p(y)}}}\n",
    "\\end{array}\n",
    "\\right .\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40a783da",
   "metadata": {},
   "source": [
    "## ID3 implementation\n",
    "Adding new feature for classification will add more information to exsiting system, which will be viewed as conditional probability entropy. <br>\n",
    "The formula evolution should be viewed like IG:\n",
    "$$\n",
    "\\begin{array}{ll}\n",
    "    IG(D,a) & = & H(D) - H(D|a) \\\\\n",
    "    & = & Ent(D) - \\sum{\\frac{|D_v|}{|D|}Ent(D^v)} \\\\\n",
    "\\end{array}\n",
    "$$\n",
    "* here D means dataset <br>\n",
    "* a is one classification feature, which has v different values <br>\n",
    "* $D_v$ means data falls into v category\n",
    "* $Ent(D^v)$ is $H(D|a=v)$ probability distribution in category v\n",
    "* $\\frac{|D_v|}{|D|}$ is $p(y)$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44d1ae4c",
   "metadata": {},
   "source": [
    "## python implementation\n",
    "1. <font color=sapphire><b>sklearn.feature_selection mutual_info_classif</font></b> will return mutual information between each feature and its target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "61611753",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.feature_selection import mutual_info_classif\n",
    "from sklearn.datasets import load_iris\n",
    "\n",
    "iris_raw = load_iris()\n",
    "iris_raw.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "161025f3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "feaeture name: sepal length (cm) - 0.486408.5\n",
      "feaeture name: sepal width (cm) - 0.297351.5\n",
      "feaeture name: petal length (cm) - 0.991710.5\n",
      "feaeture name: petal width (cm) - 0.988400.5\n"
     ]
    }
   ],
   "source": [
    "X_iris = iris_raw.data\n",
    "y_iris = iris_raw.target\n",
    "feature_iris = iris_raw.feature_names\n",
    "mic = mutual_info_classif(X_iris, y_iris)\n",
    "for feat, mic_value in zip(feature_iris, mic):\n",
    "    print(\"feaeture name: %s - %f.5\"%(feat, mic_value))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55c1dcd3",
   "metadata": {},
   "source": [
    "# $\\chi^2$ test\n",
    "    > Mostly test for degree of correlation of two different sets of features. <br>\n",
    "    > The null hypothesus is independence between two features.  <br>\n",
    "    > DOF equals to $(r-1)(c-1)$ <br>\n",
    "## basic principle\n",
    "    > If two sets of features are independent to each other, the product of their marginal probability distribution should just equal to their joint probability distribution, which is:\n",
    "$$\n",
    "    P(X,Y) = P(X)\\cdot P(Y)\n",
    "$$\n",
    "\n",
    "    > Then, the difference between observed value and principle value should be just random noise, which in statistics obeying standard normal distribution.<br>\n",
    "    > Thus we could construct hypothesis test pivot statistic:\n",
    "$$\n",
    "\\begin{array}{ll}\n",
    "    & \\chi^2(\\nu) = \\sum_{i}^{N}{\\frac{{(O_i-E_i)}^2}{E_i}} \\\\\n",
    "    & * \\space N \\space equals \\space to \\space item \\space numbers \\space in \\space cross-table\n",
    "\\end{array}\n",
    "$$\n",
    "\n",
    "## special case\n",
    "    > for classic $2 \\times 2$ cross-table:\n",
    "<table>\n",
    "    <th></th>\n",
    "    <th>Cat1-Val1</th>\n",
    "    <th>Cat1-Val2</th>\n",
    "    <th>Sum</th>\n",
    "    <tr>\n",
    "        <td>Cat2-Val1</td>\n",
    "        <td>a</td>\n",
    "        <td>b</td>\n",
    "        <td>a+b</td>\n",
    "    </tr>\n",
    "    <tr>\n",
    "        <td>Cat2-Val2</td>\n",
    "        <td>c</td>\n",
    "        <td>d</td>\n",
    "        <td>c+d</td>\n",
    "    </tr>\n",
    "    <tr>\n",
    "        <td>Sum</td>\n",
    "        <td>a+c</td>\n",
    "        <td>b+d</td>\n",
    "        <td>n=a+b+c+d</td>\n",
    "    </tr>\n",
    "</table>\n",
    "\n",
    "    > the constructed statistic is:\n",
    "$$\n",
    "\\begin{array}{ll}\n",
    "    & \\chi^2(\\nu) = \\frac{n{(ad-bc)}^2}{(a+c)(b+d)(a+b)(c+d)} \\\\\n",
    "    & * \\space\\nu = (r-1)(c-1) = 1\n",
    "\\end{array}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14dc74df",
   "metadata": {},
   "source": [
    "## python implementation\n",
    "1. <font color=sapphire><b> sklearn.feature_selection chi2</b></font>\n",
    "2. for chi2 hypothesis test, make sure label vector could be binarized, which is not continuous"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce2ff134",
   "metadata": {},
   "source": [
    "### between label and feature"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "feae3b6b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "feature: sepal length (cm) - True\n",
      "feature: sepal width (cm) - False\n",
      "feature: petal length (cm) - True\n",
      "feature: petal width (cm) - True\n"
     ]
    }
   ],
   "source": [
    "from sklearn.feature_selection import chi2\n",
    "\n",
    "c2 = chi2(X_iris, y_iris)\n",
    "res = c2[1] < 0.05\n",
    "for feat, c2_val in zip(feature_iris, res):\n",
    "    print(\"feature: %s - %s\"%(feat, c2_val))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2965981",
   "metadata": {},
   "source": [
    "### between features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "fe52ff25",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1.4, 13), (1.5, 13), (4.5, 8), (5.1, 8), (1.3, 7)]"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from collections import Counter\n",
    "\n",
    "c = Counter(X_iris[:,2])\n",
    "c.most_common(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "81ebf1fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([153.52776089]), array([1.28055921e-14]))"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# test for 2 sets of features\n",
    "# first, one feature in X postion should be transformed into 2-d matrix, using reshap(-1,1)\n",
    "# second, make sure the other feature be changed to type int using astype(int)\n",
    "# chi-square test with two lengths in sepal and petal\n",
    "slen_iris = X_iris[:,0].reshape(-1,1)\n",
    "plen_iris = X_iris[:,2]\n",
    "c2_len = chi2(slen_iris*10,(plen_iris*10).astype(np.int8))\n",
    "c2_len"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4858e1d7",
   "metadata": {},
   "source": [
    "# F test\n",
    "1. <font color=sapphire><b>f_classif</b></font> is used to test discrete values\n",
    "2. <font color=sapphire><b>f_regression</b></font> is used to test continuous values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "b0b06ec0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.89047835e-32, 5.20156326e-08, 4.20187315e-76, 4.15531102e-81])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.feature_selection import f_classif\n",
    "from sklearn.feature_selection import f_regression\n",
    "\n",
    "f, pval = f_regression(X_iris, y_iris)\n",
    "pval"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "62f07d68",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f2, pval2 = f_regression(slen_iris, plen_iris)\n",
    "pval2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0eb4754f",
   "metadata": {},
   "source": [
    "# correlation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "e01157ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:>"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "sns.set(rc={'figure.figsize':(8,5)})\n",
    "sns.heatmap(np.corrcoef(X_iris, rowvar=False),\n",
    "annot=True,\n",
    "linewidths=.5,\n",
    "center=0,\n",
    "cbar=False,\n",
    "cmap=\"PiYG\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "d9566773",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(150, 4)"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_iris.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ac178ed",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3.6",
   "language": "python",
   "name": "python3.6"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
